package com.fr.chart.core;

import com.fr.base.core.json.JSONException;
import com.fr.base.core.json.JSONObject;
import com.fr.base.xml.XMLPrintWriter;
import com.fr.base.xml.XMLReadable;
import com.fr.base.xml.XMLableReader;
import com.fr.chart.LineStyleInfo;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;

public class TrendLine extends FoldLine
{
  private static final long serialVersionUID = -993509754275088848L;
  public static int LINEAR = 0;
  public static int POLYNOMIAL = 1;
  public static int LOG = 2;
  public static int EXPONENT = 3;
  public static int POWER = 4;
  private double[] val = new double[2];
  private int equation = POLYNOMIAL;
  private double R = 0.0D;
  private int square = 6;

  public TrendLine()
  {
  }

  public TrendLine(int paramInt)
  {
    setEquation(paramInt);
  }

  public void setEquation(int paramInt)
  {
    this.equation = paramInt;
  }

  public int getEquation()
  {
    return this.equation;
  }

  public double getR()
  {
    return this.R;
  }

  public Shape getTrendLine()
  {
    return getGeneralPath();
  }

  public void setSquare(int paramInt)
  {
    this.square = paramInt;
  }

  public int getSquare()
  {
    return this.square;
  }

  public void drawShape(Rectangle2D paramRectangle2D)
  {
    if ((getEquation() < 0) || (getEquation() > 4))
      return;
    int i = 1;
    GeneralPath localGeneralPath = new GeneralPath();
    double d1 = paramRectangle2D.getX();
    while (d1 < paramRectangle2D.getWidth() + paramRectangle2D.getX())
    {
      double d2 = calculator(d1);
      if ((d2 > paramRectangle2D.getHeight()) || (d2 < 0.0D))
      {
        i = 1;
      }
      else if (i != 0)
      {
        localGeneralPath.moveTo((float)d1, (float)d2);
        i = 0;
      }
      else
      {
        localGeneralPath.lineTo((float)d1, (float)d2);
      }
      d1 += 1.0D;
    }
    setGeneralPath(localGeneralPath);
  }

  public void fitting(double[] paramArrayOfDouble1, double[] paramArrayOfDouble2)
  {
    if (paramArrayOfDouble1.length != paramArrayOfDouble2.length)
      return;
    this.square = ((this.square > paramArrayOfDouble1.length - 1) ? paramArrayOfDouble1.length - 1 : this.square);
    if (getEquation() == LINEAR)
      linear(paramArrayOfDouble1, paramArrayOfDouble2);
    else if (getEquation() == POLYNOMIAL)
      polynomial(paramArrayOfDouble1, paramArrayOfDouble2, this.square);
    else if (getEquation() == LOG)
      log(paramArrayOfDouble1, paramArrayOfDouble2);
    else if (getEquation() == EXPONENT)
      exponent(paramArrayOfDouble1, paramArrayOfDouble2);
    else if (getEquation() == POWER)
      power(paramArrayOfDouble1, paramArrayOfDouble2);
    calR(paramArrayOfDouble1, paramArrayOfDouble2);
  }

  public String toString()
  {
    if (getEquation() == LINEAR)
    {
      if (this.val[1] < 0.0D)
        return this.val[0] + " * x - " + (-this.val[1]);
      return this.val[0] + " * x + " + this.val[1];
    }
    if (getEquation() == POLYNOMIAL)
    {
      String str1;
      String str2;
      if (this.val[0] < 0.0D)
      {
        str1 = (-this.val[0]) + "";
        str2 = "-";
      }
      else
      {
        str1 = this.val[0] + "";
        str2 = "+";
      }
      for (int i = 1; i < this.val.length; ++i)
      {
        str1 = " * POWER(x, " + i + ") " + str2 + " " + str1;
        if (this.val[i] < 0.0D)
        {
          str1 = (-this.val[i]) + str1;
          str2 = "-";
        }
        else
        {
          str1 = this.val[i] + str1;
          str2 = "+";
        }
      }
      return str1;
    }
    if (getEquation() == LOG)
    {
      if (this.val[1] < 0.0D)
        return this.val[0] + " * LN(x) - " + (-this.val[1]);
      return this.val[0] + " * LN(x) + " + this.val[1];
    }
    if (getEquation() == EXPONENT)
      return this.val[0] + " * EXP(" + this.val[1] + " * x)";
    if (getEquation() == POWER)
      return this.val[0] + " * POWER(x, " + this.val[1] + ")";
    return "";
  }

  public Object clone()
  {
    TrendLine localTrendLine = new TrendLine(this.equation);
    localTrendLine.square = this.square;
    localTrendLine.setLineStyleInfo(getLineStyleInfo());
    return localTrendLine;
  }

  public void readXML(XMLableReader paramXMLableReader)
  {
    if (paramXMLableReader.isChildNode())
    {
      String str1 = paramXMLableReader.getTagName();
      if (str1.equals("LineStyleInfo"))
      {
        paramXMLableReader.readXMLObject(new XMLReadable(this)
        {
          private final TrendLine this$0;

          public void readXML()
          {
            String str = paramXMLableReader.getTagName();
            if (str.equals("LineStyleInfo"))
              this.this$0.setLineStyleInfo((LineStyleInfo)paramXMLableReader.readXMLObject(new LineStyleInfo()));
          }
        });
      }
      else if (str1.equals("Attr"))
      {
        String str2;
        if ((str2 = paramXMLableReader.getAttr("square")) != null)
          this.square = Integer.valueOf(str2).intValue();
        if ((str2 = paramXMLableReader.getAttr("equation")) != null)
          this.equation = Integer.valueOf(str2).intValue();
      }
    }
  }

  public void writeXML(XMLPrintWriter paramXMLPrintWriter)
  {
    paramXMLPrintWriter.startTAG("TrendLine");
    paramXMLPrintWriter.startTAG("Attr").attr("equation", this.equation).attr("square", this.square).end();
    getLineStyleInfo().writeXML(paramXMLPrintWriter);
    paramXMLPrintWriter.end();
  }

  public JSONObject toJSONObject()
    throws JSONException
  {
    JSONObject localJSONObject = new JSONObject();
    localJSONObject.put("equation", this.equation);
    localJSONObject.put("square", this.square);
    localJSONObject.put("lineColor", ChartUtils.color2JS(getLineStyleInfo().getSeriesLineColor()));
    localJSONObject.put("lineStyle", getLineStyleInfo().getSeriesLineStyle());
    return localJSONObject;
  }

  protected void calR(double[] paramArrayOfDouble1, double[] paramArrayOfDouble2)
  {
    double[] arrayOfDouble = new double[paramArrayOfDouble2.length];
    for (int i = 0; i < paramArrayOfDouble1.length; ++i)
      arrayOfDouble[i] = calculator(paramArrayOfDouble1[i]);
    double d1 = 0.0D;
    double d2 = 0.0D;
    double d3 = 0.0D;
    for (int j = 0; j < paramArrayOfDouble2.length; ++j)
    {
      d1 += (arrayOfDouble[j] - paramArrayOfDouble2[j]) * (arrayOfDouble[j] - paramArrayOfDouble2[j]);
      d3 += paramArrayOfDouble2[j];
      d2 += paramArrayOfDouble2[j] * paramArrayOfDouble2[j];
    }
    d2 -= d3 * d3 / paramArrayOfDouble2.length;
    this.R = (1.0D - d1 / d2);
  }

  protected double calculator(double paramDouble)
  {
    if (getEquation() == LINEAR)
      return linearFunc(paramDouble);
    if (getEquation() == POLYNOMIAL)
      return polynomialFunc(paramDouble);
    if (getEquation() == LOG)
      return logFunc(paramDouble);
    if (getEquation() == EXPONENT)
      return exponentFunc(paramDouble);
    if (getEquation() == POWER)
      return powerFunc(paramDouble);
    return (0.0D / 0.0D);
  }

  protected void linear(double[] paramArrayOfDouble1, double[] paramArrayOfDouble2)
  {
    double d1 = 0.0D;
    double d2 = 0.0D;
    double d3 = 0.0D;
    double d4 = 0.0D;
    int i = paramArrayOfDouble1.length;
    for (int j = 0; j < paramArrayOfDouble1.length; ++j)
    {
      d1 += paramArrayOfDouble1[j];
      d2 += paramArrayOfDouble2[j];
      d3 += paramArrayOfDouble1[j] * paramArrayOfDouble1[j];
      d4 += paramArrayOfDouble1[j] * paramArrayOfDouble2[j];
    }
    if (d1 * d1 - d3 * i == 0.0D)
      return;
    this.val[0] = ((d2 * d1 - d4 * i) / (d1 * d1 - d3 * i));
    this.val[1] = ((d2 - d1 * this.val[0]) / i);
  }

  protected void polynomial(double[] paramArrayOfDouble1, double[] paramArrayOfDouble2, int paramInt)
  {
    double d;
    int i3;
    int i4;
    double[][] arrayOfDouble1 = new double[++paramInt][paramArrayOfDouble1.length];
    double[][] arrayOfDouble2 = new double[paramInt][paramInt];
    double[] arrayOfDouble3 = new double[paramInt];
    double[] arrayOfDouble4 = new double[paramInt];
    this.val = new double[paramInt];
    for (int i = 0; i < paramInt; ++i)
      for (i3 = 0; i3 < paramArrayOfDouble1.length; ++i3)
      {
        d = 1.0D;
        for (int i8 = 0; i8 < i; ++i8)
          d *= paramArrayOfDouble1[i3];
        arrayOfDouble1[i][i3] = d;
      }
    for (int j = 0; j < paramInt; ++j)
      for (int i5 = 0; i5 < paramInt; ++i5)
      {
        d = 0.0D;
        for (i3 = 0; i3 < paramArrayOfDouble1.length; ++i3)
          d += arrayOfDouble1[j][i3] * arrayOfDouble1[i5][i3];
        arrayOfDouble2[j][i5] = d;
      }
    for (int k = 0; k < paramInt; ++k)
    {
      d = 0.0D;
      for (i3 = 0; i3 < paramArrayOfDouble1.length; ++i3)
        d += paramArrayOfDouble2[i3] * arrayOfDouble1[k][i3];
      arrayOfDouble3[k] = d;
    }
    for (int l = 1; l < paramInt; ++l)
      arrayOfDouble2[l][0] /= arrayOfDouble2[0][0];
    for (int i1 = 1; i1 < paramInt; ++i1)
      for (i3 = i1; i3 < paramInt; ++i3)
      {
        d = 0.0D;
        for (int i6 = 0; i6 < i1; ++i6)
          d += arrayOfDouble2[i6][i3] * arrayOfDouble2[i1][i6];
        arrayOfDouble2[i1][i3] -= d;
        if (i3 + 1 != paramInt)
        {
          d = 0.0D;
          for (int i7 = 0; i7 < i1; ++i7)
            d += arrayOfDouble2[i7][i1] * arrayOfDouble2[(i3 + 1)][i7];
          arrayOfDouble2[(i3 + 1)][i1] = ((arrayOfDouble2[(i3 + 1)][i1] - d) / arrayOfDouble2[i1][i1]);
        }
      }
    arrayOfDouble4[0] = arrayOfDouble3[0];
    for (int i2 = 1; i2 < paramInt; ++i2)
    {
      d = 0.0D;
      for (i4 = 0; i4 < i2; ++i4)
        d += arrayOfDouble2[i2][i4] * arrayOfDouble4[i4];
      arrayOfDouble4[i2] = (arrayOfDouble3[i2] - d);
    }
    this.val[(paramInt - 1)] = (arrayOfDouble4[(paramInt - 1)] / arrayOfDouble2[(paramInt - 1)][(paramInt - 1)]);
    for (i2 = paramInt - 2; i2 >= 0; --i2)
    {
      d = 0.0D;
      for (i4 = i2 + 1; i4 < paramInt; ++i4)
        d += arrayOfDouble2[i2][i4] * this.val[i4];
      this.val[i2] = ((arrayOfDouble4[i2] - d) / arrayOfDouble2[i2][i2]);
    }
  }

  protected void log(double[] paramArrayOfDouble1, double[] paramArrayOfDouble2)
  {
    int i = 0;
    for (int j = 0; j < paramArrayOfDouble1.length; ++j)
      if (paramArrayOfDouble1[j] > 0.0D)
        ++i;
    double[] arrayOfDouble1 = new double[i];
    double[] arrayOfDouble2 = new double[i];
    i = 0;
    for (int k = 0; k < paramArrayOfDouble1.length; ++k)
      if (paramArrayOfDouble1[k] > 0.0D)
      {
        arrayOfDouble1[i] = Math.log(paramArrayOfDouble1[k]);
        arrayOfDouble2[i] = paramArrayOfDouble2[k];
        ++i;
      }
    linear(arrayOfDouble1, arrayOfDouble2);
  }

  protected void exponent(double[] paramArrayOfDouble1, double[] paramArrayOfDouble2)
  {
    int i = 0;
    for (int j = 0; j < paramArrayOfDouble1.length; ++j)
      if (paramArrayOfDouble2[j] > 0.0D)
        ++i;
    double[] arrayOfDouble1 = new double[i];
    double[] arrayOfDouble2 = new double[i];
    i = 0;
    for (int k = 0; k < paramArrayOfDouble2.length; ++k)
      if (paramArrayOfDouble2[k] > 0.0D)
      {
        arrayOfDouble1[i] = paramArrayOfDouble1[k];
        arrayOfDouble2[i] = Math.log(paramArrayOfDouble2[k]);
        ++i;
      }
    linear(arrayOfDouble1, arrayOfDouble2);
    double d = this.val[0];
    this.val[0] = Math.exp(this.val[1]);
    this.val[1] = d;
  }

  protected void power(double[] paramArrayOfDouble1, double[] paramArrayOfDouble2)
  {
    int i = 0;
    for (int j = 0; j < paramArrayOfDouble1.length; ++j)
      if ((paramArrayOfDouble1[j] > 0.0D) && (paramArrayOfDouble2[j] > 0.0D))
        ++i;
    double[] arrayOfDouble1 = new double[i];
    double[] arrayOfDouble2 = new double[i];
    i = 0;
    for (int k = 0; k < paramArrayOfDouble1.length; ++k)
      if ((paramArrayOfDouble1[k] > 0.0D) && (paramArrayOfDouble2[k] > 0.0D))
      {
        arrayOfDouble1[i] = Math.log(paramArrayOfDouble1[k]);
        arrayOfDouble2[i] = Math.log(paramArrayOfDouble2[k]);
        ++i;
      }
    linear(arrayOfDouble1, arrayOfDouble2);
    double d = this.val[0];
    this.val[0] = Math.exp(this.val[1]);
    this.val[1] = d;
  }

  protected double linearFunc(double paramDouble)
  {
    return (this.val[0] * paramDouble + this.val[1]);
  }

  protected double polynomialFunc(double paramDouble)
  {
    double d = 0.0D;
    for (int i = 0; i < this.val.length; ++i)
      d += this.val[i] * Math.pow(paramDouble, i);
    return d;
  }

  protected double logFunc(double paramDouble)
  {
    if (paramDouble <= 0.0D)
      return (0.0D / 0.0D);
    return (this.val[0] * Math.log(paramDouble) + this.val[1]);
  }

  protected double exponentFunc(double paramDouble)
  {
    return (this.val[0] * Math.exp(paramDouble * this.val[1]));
  }

  protected double powerFunc(double paramDouble)
  {
    return (this.val[0] * Math.pow(paramDouble, this.val[1]));
  }
}